import classNames from "classnames"
import React, { ChangeEvent, ReactElement, useRef } from "react"
import Icon from "../Icon/icon"
import { IconProp } from "@fortawesome/fontawesome-svg-core";

type InputSize = 'lg' | 'sm'

/**
 * 这里引入ts的一个新语法Omit，忽略类里的属性，只保留我们需要的属性
 * 由于我们定义的size是string类型，但是原生input内置的size是number类型，所以会报错
 * 使用Omit将原生input内置的size属性忽略掉
 */
export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>,'size'> {
    disabled?:boolean,
    size?:InputSize,
    icon?: IconProp;
    // input前缀
    prepend?:string | ReactElement,
    // input后缀
    append?:string | ReactElement,
    className?:string,
    onChange?:(e:ChangeEvent<HTMLInputElement>) => void
    allowClear?:boolean,
    onClear?:() => void
}

const Input = ({
    disabled,
    size,
    style,
    icon,
    append,
    prepend,
    allowClear,
    onClear,
    ...restProps
}: InputProps) => { 
    const classes = classNames('leo-input-wrapper',{
        [`input-size-${size}`]: size,
        'is-disabled': disabled,
        'input-group': prepend || append,
        'input-group-append': !!append,
        'input-group-prepend': !!prepend
    })
    const fixControlledValue = (value: any) => {
        if (typeof value === 'undefined' || value === null) {
          return ''
        }
        return value
    }
    if('value' in restProps) {
        delete restProps.defaultValue
        restProps.value = fixControlledValue(restProps.value)
    }
    const ref = useRef<HTMLInputElement | null>(null)
    const handClear:any  = (e:React.ChangeEvent<HTMLInputElement>)=> {
        onClear && onClear()
        e.target.value = ''
        ref.current?.focus()
        restProps.onChange && restProps?.onChange(e)
    }
    return (
        <div className={classes} style={style}>
            { icon && <div className="icon-wrapper"><Icon icon={icon}></Icon></div>}
            { allowClear && restProps.value && !icon &&  <div className="icon-wrapper" style={{cursor:'pointer'}} onClick={handClear}><Icon icon="circle-xmark"></Icon></div> }
            { prepend && <div className="leo-input-group-prepend">{ prepend }</div> }
            <input 
                ref={ref}
                className="leo-input-inner"
                disabled={disabled}
                {...restProps} 
            />
            { append && <div className="leo-input-group-append">{ append }</div> }
        </div>
        
    )
}

export default Input